#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
from pylab import mpl
from datetime import datetime, timedelta
from django.core.exceptions import ValidationError
from django.db.utils import DataError
from django.db.models import Q
from web.util.dto_util import DtoUtil
from web.util.datetime_util import DatetimeUtil
from web.util.math_util import MathUtil
from web.constants.k_line_period_type import KLinePeriodType
from web.constants.datetime_format import DatetimeFormat
from web.manager.log_manager import LogManager
from web.models.commodity_future_week_contract_data import CommodityFutureWeekContractData
from web.service.base_service import BaseService
# from web.config.create_week_picture_config import CreateWeekPictureConfig
from web.config.commodity_future_week_contract_data_config import CommodityFutureWeekContractDataConfig

Logger = LogManager.get_logger(__name__)

"""
CommodityFutureWeekContractData的service类
"""


class CommodityFutureWeekContractDataService(BaseService):

    ########################################### 全量计算数据 ########################################

    def write_week_contract_basic_data(self):
        """
        计算周线级别基础数据
        """

        Logger.info("计算周线级别基础数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_basic_data()

    def write_week_contract_all_ma(self):
        """
        计算周线级别全部MA数据
        """

        Logger.info("计算周线级别全部MA数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_all_ma()

    def write_week_contract_all_kd(self):
        """
        计算周线级别全部KD数据
        """

        Logger.info("计算周线级别全部KD数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_all_kd()

    def write_week_contract_all_macd(self):
        """
        计算周线级别全部MACD数据
        """

        Logger.info("计算周线级别全部MACD数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_all_macd()

    def write_week_contract_all_boll(self):
        """
        计算周线级别全部BOLL数据
        """

        Logger.info("计算周线级别全部BOLL数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_all_boll()

    def write_week_contract_all_ha(self):
        """
        计算周线级别全部HA数据
        """

        Logger.info("计算周线级别全部HA数据")

        self.commodity_future_week_contract_data_dao.write_week_contract_all_ha()

    ########################################### 增量计算数据 ########################################

    def write_week_contract_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的基础数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的基础数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_By_End_Date)

    def write_week_contract_ma_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的MA数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的MA数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ma_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ma_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_ma_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ma_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ma_By_End_Date)

    def write_week_contract_kd_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的KD数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的KD数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Kd_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Kd_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_kd_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Kd_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Kd_By_End_Date)

    def write_week_contract_macd_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的MACD数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的MACD数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Macd_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Macd_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_macd_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Macd_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Macd_By_End_Date)

    def write_week_contract_boll_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的BOLL数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的BOLL数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Boll_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Boll_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_boll_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Boll_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Boll_By_End_Date)

    def write_week_contract_ha_by_date(self):
        """
        根据日期，计算周线级别某一个交易周的HA数据（具体合约）
        """

        Logger.info("根据日期，计算周线级别交易周[%s]和[%s]的HA数据（具体合约）",
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ha_By_Begin_Date,
                    CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ha_By_End_Date)

        self.commodity_future_week_contract_data_dao.write_week_contract_ha_by_date(
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ha_By_Begin_Date,
            CommodityFutureWeekContractDataConfig.Commodity_Future_Week_Contract_Data_Ha_By_End_Date)

    #################################################### 创建图片 ################################################
    # def create_price_change_up_percentage_picture(self):
    #     """
    #     创建图片：周线级别上涨的期货的百分比
    #     """
    #
    #     Logger.info("周线级别上涨的期货的百分比，时间从[%s]至[%s]", CreateWeekPictureConfig.Price_Change_Up_Percentage_Begin_Date,
    #                 CreateWeekPictureConfig.Price_Change_Up_Percentage_End_Date)
    #
    #     begin_date_and_end_date_tuple = self.stock_index_week_dao.find_begin_data_and_end_date_between_and_order_by(
    #         CreateWeekPictureConfig.Price_Change_Up_Percentage_Begin_Date,
    #         CreateWeekPictureConfig.Price_Change_Up_Percentage_End_Date)
    #
    #     transaction_date_array = list()
    #     price_change_up_percentage_array = list()
    #     middle_line_array = list()
    #     min_begin_date_and_max_end_date_5_date_array = list()
    #     for begin_date_and_end_date in begin_date_and_end_date_tuple:
    #         percentage_tuple = self.commodity_future_date_data_dao.find_date_price_change_up_percentage_between_transaction_date(
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[0], DatetimeFormat.Date_Format_With_Line),
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[1], DatetimeFormat.Date_Format_With_Line))
    #
    #         # 5日均线
    #         min_begin_date_and_max_end_date_5_date_tuple = self.stock_index_week_dao.find_max_end_date_and_min_begin_date_between(
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[0], DatetimeFormat.Date_Format_With_Line),
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[1], DatetimeFormat.Date_Format_With_Line), 5)
    #         average_price_change_5_date_tuple = self.commodity_future_date_data_dao.average_price_change_up_percentage_between_transaction_date(
    #             DatetimeUtil.datetime_to_str(min_begin_date_and_max_end_date_5_date_tuple[0][0],
    #                                          DatetimeFormat.Date_Format_With_Line),
    #             DatetimeUtil.datetime_to_str(min_begin_date_and_max_end_date_5_date_tuple[0][1],
    #                                          DatetimeFormat.Date_Format_With_Line), 5)
    #
    #         for percentage in percentage_tuple:
    #             transaction_date_array.append(
    #                 DatetimeUtil.datetime_to_str(begin_date_and_end_date[1], DatetimeFormat.Date_Format_With_Line))
    #             price_change_up_percentage_array.append(percentage[0])
    #             middle_line_array.append(50)
    #             min_begin_date_and_max_end_date_5_date_array.append(average_price_change_5_date_tuple[0][0])
    #
    #     # 创建一个新的图表
    #     fig, ax = plt.subplots(figsize=(18, 8))
    #
    #     # 关闭交互模式
    #     plt.ioff()
    #
    #     mpl.rcParams["font.sans-serif"] = ["SimHei"]
    #
    #     # 创建折线图
    #     ax.plot(transaction_date_array, middle_line_array, label='中轴线', linewidth=0.5,
    #             marker='o',
    #             color='red')
    #     ax.plot(transaction_date_array, price_change_up_percentage_array, label='上涨的期货的百分比',
    #             linewidth=0.5,
    #             marker='o', color='black')
    #     ax.plot(transaction_date_array, min_begin_date_and_max_end_date_5_date_array, label='上涨的期货的百分比（5日均线）',
    #             linewidth=0.5,
    #             marker='o', color='blue')
    #     plt.legend()
    #     plt.title('周线级别上涨的期货的百分比')
    #     plt.xlabel('时间')
    #     plt.ylabel('百分比')
    #
    #     # 分辨率
    #     plt.rcParams['savefig.dpi'] = 300
    #
    #     # 显示图例
    #     # plt.legend()
    #
    #     # 保存图表
    #     plt.savefig(CreateWeekPictureConfig.Price_Change_Up_Percentage_Save_Path)
    #
    #     # 显示图表
    #     # plt.show()
    #
    #     # 关闭图表
    #     plt.close()
    #
    # def create_week_average_kd_picture(self):
    #     """
    #     创建图片：根据开始时间和结束时间，周线级别平均KD
    #     """
    #     Logger.info("创建图片：根据开始时间和结束时间，周线级别平均KD，时间从[%s]至[%s]", CreateWeekPictureConfig.Average_KD_Begin_Date,
    #                 CreateWeekPictureConfig.Average_KD_End_Date)
    #
    #     begin_date_and_end_date_tuple = self.stock_index_week_dao.find_begin_data_and_end_date_between_and_order_by(
    #         CreateWeekPictureConfig.Average_KD_Begin_Date,
    #         CreateWeekPictureConfig.Average_KD_End_Date)
    #
    #     transaction_date_array = list()
    #     average_k_array = list()
    #     average_d_array = list()
    #     unite_relative_price_index_date_close_price_array = list()
    #     for begin_date_and_end_date in begin_date_and_end_date_tuple:
    #         average_kd_tuple = self.commodity_future_week_data_dao.find_average_kd_by_begin_date_and_end_date(
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[0], DatetimeFormat.Date_Format_With_Line),
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[1], DatetimeFormat.Date_Format_With_Line))
    #         average_k_array.append(average_kd_tuple[0][0])
    #         average_d_array.append(average_kd_tuple[0][1])
    #         transaction_date_array.append(begin_date_and_end_date[0])
    #         unite_relative_price_index_date = self.unite_relative_price_index_date_dao.find_by_transaction_date(
    #             DatetimeUtil.datetime_to_str(begin_date_and_end_date[1], DatetimeFormat.Date_Format_With_Line))
    #         unite_relative_price_index_date_close_price_array.append(unite_relative_price_index_date.close_price)
    #
    #     # 创建一个新的图表
    #     fig, ax = plt.subplots(figsize=(18, 8))
    #
    #     # 关闭交互模式
    #     plt.ioff()
    #
    #     mpl.rcParams["font.sans-serif"] = ["SimHei"]
    #
    #     # 创建折线图
    #     ax.plot(transaction_date_array, MathUtil.normalize(average_k_array)[0], label='平均K值', linewidth=0.5,
    #             marker='o',
    #             color='blue')
    #     ax.plot(transaction_date_array, MathUtil.normalize(average_d_array)[0], label='平均D值',
    #             linewidth=0.5,
    #             marker='o', color='green')
    #     ax.plot(transaction_date_array, MathUtil.normalize(unite_relative_price_index_date_close_price_array)[0],
    #             label='统一相对价格指数周线级别收盘价',
    #             linewidth=0.5,
    #             marker='o', color='red')
    #     plt.legend()
    #     plt.title('周线级别平均KD')
    #     plt.xlabel('时间')
    #     plt.ylabel('百分比')
    #
    #     # 分辨率
    #     plt.rcParams['savefig.dpi'] = 300
    #
    #     # 显示图例
    #     # plt.legend()
    #
    #     # 保存图表
    #     plt.savefig(CreateWeekPictureConfig.Average_KD_Save_Path)
    #
    #     # 显示图表
    #     # plt.show()
    #
    #     # 关闭图表
    #     plt.close()
